package cn.cyh.queue_service.service.impl;

import cn.cyh.queue_service.common.Constants;
import cn.cyh.queue_service.common.Result;
import cn.cyh.queue_service.common.ResultCode;
import cn.cyh.queue_service.config.security.JwtTokenProvider;
import cn.cyh.queue_service.exception.BusinessException;
import cn.cyh.queue_service.mapper.UserMapper;
import cn.cyh.queue_service.model.dto.LoginRequest;
import cn.cyh.queue_service.model.dto.LoginResponse;
import cn.cyh.queue_service.model.dto.PageRequest;
import cn.cyh.queue_service.model.dto.PageResult;
import cn.cyh.queue_service.model.dto.RegisterRequest;
import cn.cyh.queue_service.model.entity.User;
import cn.cyh.queue_service.model.vo.UserVO;
import cn.cyh.queue_service.service.UserService;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.mindrot.jbcrypt.BCrypt;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    
    private final JwtTokenProvider jwtTokenProvider;
    private final UserMapper userMapper;
    
    @Value("${spring.profiles.active:prod}")
    private String activeProfile;

    @Override
    public LoginResponse login(LoginRequest request) {
        // 判断是否使用模拟登录（仅开发环境）
        if (Boolean.TRUE.equals(request.getUseSimulatedLogin()) && "dev".equals(activeProfile)) {
            log.warn("使用模拟登录：{}", request.getUsername());
            return simulateLogin(request.getUsername());
        }
        
        // 查询用户
        User user = getByUsername(request.getUsername());
        if (user == null) {
            throw new BusinessException(ResultCode.USER_NOT_FOUND);
        }
        
        // 验证密码
        if (!BCrypt.checkpw(request.getPassword(), user.getPassword())) {
            throw new BusinessException(ResultCode.PASSWORD_ERROR);
        }
        
        // 验证用户状态
        if (user.getStatus() == 0) {
            throw new BusinessException(ResultCode.USER_DISABLED);
        }
        
        // 更新最后登录时间
        userMapper.updateLastLoginTime(user.getId());
        
        // 生成token
        String token = jwtTokenProvider.createToken(user.getUsername(), user.getRole());
        log.debug("请注意生成的token！！！！！！：{}", token);
        // 构建用户视图对象
        UserVO userVO = convertToUserVO(user);
        
        // 构建响应
        return LoginResponse.builder()
                .userId(user.getId())
                .username(user.getUsername())
                .name(user.getName())
                .role(user.getRole())
                .avatar(user.getAvatar())
                .token(token)
                .tokenType("Bearer")
                .expiresIn(jwtTokenProvider.getValidityInMilliseconds())
                .userInfo(userVO)
                .build();
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long register(RegisterRequest request) {
        // 验证用户名是否存在
        if (isUsernameExists(request.getUsername())) {
            throw new BusinessException(ResultCode.USERNAME_EXISTS);
        }
        
        // 创建用户
        User user = User.builder()
                .username(request.getUsername())
                .password(BCrypt.hashpw(request.getPassword(), BCrypt.gensalt()))
                .name(request.getName())
                .phone(request.getPhone())
                .email(request.getEmail())
                .avatar(StrUtil.isBlank(request.getAvatar()) ? Constants.DEFAULT_AVATAR : request.getAvatar())
                .role(StrUtil.isBlank(request.getRole()) ? "operator" : request.getRole())
                .status(1)
                .createTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .build();
        
        // 保存用户
        save(user);
        
        return user.getId();
    }
    
    @Override
    public UserVO getUserById(Long userId) {
        User user = getById(userId);
        if (user == null) {
            throw new BusinessException(ResultCode.USER_NOT_FOUND);
        }
        
        return convertToUserVO(user);
    }
    
    @Override
    public User getByUsername(String username) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername, username);
        return getOne(queryWrapper);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateUser(Long userId, User user) {
        // 验证用户是否存在
        User existingUser = getById(userId);
        if (existingUser == null) {
            throw new BusinessException(ResultCode.USER_NOT_FOUND);
        }
        
        // 如果修改了用户名，需要验证新用户名是否存在
        if (StrUtil.isNotBlank(user.getUsername()) && !existingUser.getUsername().equals(user.getUsername())) {
            if (isUsernameExists(user.getUsername())) {
                throw new BusinessException(ResultCode.USERNAME_EXISTS);
            }
        }
        
        // 设置不可修改的字段
        user.setId(userId);
        user.setUpdateTime(LocalDateTime.now());
        
        // 如果密码为空，不修改密码
        if (StrUtil.isBlank(user.getPassword())) {
            user.setPassword(null);
        } else {
            // 加密密码
            user.setPassword(BCrypt.hashpw(user.getPassword(), BCrypt.gensalt()));
        }
        
        return updateById(user);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteUser(Long userId) {
        return removeById(userId);
    }
    
    @Override
    public PageResult<UserVO> getUserList(PageRequest pageRequest) {
        IPage<User> page = new Page<>(pageRequest.getPageNum(), pageRequest.getPageSize());
        
        // 构建查询条件
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        
        // 设置排序
        if (StrUtil.isNotBlank(pageRequest.getOrderBy())) {
            queryWrapper.orderBy(true, 
                    pageRequest.getIsAsc(), 
                    "create_time".equals(pageRequest.getOrderBy()) ? User::getCreateTime : 
                    "update_time".equals(pageRequest.getOrderBy()) ? User::getUpdateTime : 
                    User::getId);
        } else {
            queryWrapper.orderByDesc(User::getCreateTime);
        }
        
        // 执行分页查询
        page = page(page, queryWrapper);
        
        // 转换为VO
        List<UserVO> userVOList = page.getRecords().stream()
                .map(this::convertToUserVO)
                .collect(Collectors.toList());
        
        // 构建分页结果
        return PageResult.<UserVO>builder()
                .pageNum(pageRequest.getPageNum())
                .pageSize(pageRequest.getPageSize())
                .total(page.getTotal())
                .pages((int) page.getPages())
                .list(userVOList)
                .hasPrev(pageRequest.getPageNum() > 1)
                .hasNext(pageRequest.getPageNum() < page.getPages())
                .build();
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateStatus(Long userId, Integer status) {
        if (status != 0 && status != 1) {
            throw new BusinessException(ResultCode.PARAM_ERROR);
        }
        
        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(User::getId, userId)
                .set(User::getStatus, status)
                .set(User::getUpdateTime, LocalDateTime.now());
        
        return update(updateWrapper);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean resetPassword(Long userId, String newPassword) {
        if (StrUtil.isBlank(newPassword)) {
            throw new BusinessException(ResultCode.PARAM_ERROR);
        }
        
        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(User::getId, userId)
                .set(User::getPassword, BCrypt.hashpw(newPassword, BCrypt.gensalt()))
                .set(User::getUpdateTime, LocalDateTime.now());
        
        return update(updateWrapper);
    }
    
    /**
     * 验证用户名是否存在
     */
    private boolean isUsernameExists(String username) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername, username);
        return count(queryWrapper) > 0;
    }
    
    /**
     * 将用户实体转换为视图对象
     */
    private UserVO convertToUserVO(User user) {
        if (user == null) {
            return null;
        }
        
        UserVO userVO = new UserVO();
        BeanUtil.copyProperties(user, userVO);
        
        // 不返回密码
        return userVO;
    }
    
    /**
     * 模拟登录（仅开发环境使用）
     */
    private LoginResponse simulateLogin(String username) {
        User user = getByUsername(username);
        if (user == null) {
            // 模拟用户不存在时创建默认用户
            user = User.builder()
                    .username(username)
                    .password(BCrypt.hashpw("123456", BCrypt.gensalt()))
                    .name("模拟用户")
                    .phone("13800000000")
                    .email("sim@example.com")
                    .avatar(Constants.DEFAULT_AVATAR)
                    .role(Constants.ROLE_ADMIN)
                    .status(1)
                    .createTime(LocalDateTime.now())
                    .updateTime(LocalDateTime.now())
                    .build();
            
            save(user);
        }
        
        // 生成token
        String token = jwtTokenProvider.createToken(user.getUsername(), user.getRole());
        
        // 构建用户视图对象
        UserVO userVO = convertToUserVO(user);
        
        // 构建响应
        return LoginResponse.builder()
                .userId(user.getId())
                .username(user.getUsername())
                .name(user.getName())
                .role(user.getRole())
                .avatar(user.getAvatar())
                .token(token)
                .tokenType("Bearer")
                .expiresIn(jwtTokenProvider.getValidityInMilliseconds())
                .userInfo(userVO)
                .build();
    }
} 